﻿using Microsoft.Extensions.Caching.Memory;

namespace EssentialWebFramework.Common
{
    /// <summary>
    /// 供组件使用的 MemoryCache
    /// </summary>
    public class MemoryCacheForComponent
    {
        /// <summary>
        /// MemoryCache
        /// </summary>
        public static readonly IMemoryCache MemoryCache = new MemoryCache(new MemoryCacheOptions());

        /// <summary>
        /// 用于标记来源的标签
        /// </summary>
        private readonly string cacheTag;

        /// <summary>
        /// ctor
        /// </summary>
        /// <param name="cacheTag"></param>
        public MemoryCacheForComponent(string cacheTag)
        {
            this.cacheTag = cacheTag;
        }

        // MemoryCacheEntryOptions 中的
        //  SlidingExpiration 表示最后一次访问多长时间以后可以被删除
        //  AbsoluteExpiration 表示绝对过期时间
        //  AbsoluteExpirationRelativeToNow 表示相对过期时间

        /// <summary>
        /// 设置缓存
        /// </summary>
        /// <typeparam name="TItem"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="options"></param>
        public void SetCache<TItem>(object key, TItem value, MemoryCacheEntryOptions options)
        {
            MemoryCache.Set(cacheTag + key, value, options);
        }

        /// <summary>
        /// 设置缓存（带滑动过期时间）
        /// </summary>
        /// <typeparam name="TItem"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="timeSpan"></param>
        public void SetCacheSlideExpiration<TItem>(object key, TItem value, TimeSpan timeSpan)
        {
            MemoryCache.Set(cacheTag + key, value, new MemoryCacheEntryOptions
            {
                SlidingExpiration = timeSpan
            });
        }

        /// <summary>
        /// 设置缓存（带绝对过期时间）
        /// </summary>
        /// <typeparam name="TItem"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="absoluteExpiration"></param>
        /// <returns></returns>
        public TItem SetCache<TItem>(object key, TItem value, DateTimeOffset absoluteExpiration)
        {
            return MemoryCache.Set(cacheTag + key, value, absoluteExpiration);
        }

        /// <summary>
        /// 设置缓存（相对过期时间）
        /// </summary>
        /// <typeparam name="TItem"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="absoluteExpirationRelativeToNow"></param>
        /// <returns></returns>
        public TItem SetCache<TItem>(object key, TItem value, TimeSpan absoluteExpirationRelativeToNow)
        {
            return MemoryCache.Set(cacheTag + key, value, absoluteExpirationRelativeToNow);
        }

        /// <summary>
        /// 读取缓存
        /// </summary>
        /// <typeparam name="TItem"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool TryGetCacheValue<TItem>(object key, out TItem value)
        {
            return MemoryCache.TryGetValue(cacheTag + key, out value);
        }

        /// <summary>
        /// 删除缓存
        /// </summary>
        /// <param name="key"></param>
        public void RemoveCache(object key)
        {
            MemoryCache.Remove(cacheTag + key);
        }
    }
}
